【少しでも楽してコンテナイメージを減らしたかった】コンテナイメージサイズを縮小するためにDive使ってイメージを分析してみた
こんばんわ、札幌のヨシエです。
コンテナを使用する時に必要となるものがコンテナイメージです。
このコンテナイメージは小さければ小さいほど正義として扱われ、この正義を通すために人はアレやコレやと試行錯誤を繰り返してコンテナイメージ縮小の旅に出ます。
その旅に持っていけると良いツールとしてDiveを試してみたので紹介させていただきます。
検証用コンテナイメージ
今回の検証は軽量コンテナイメージを元にして、Dockerfileによるレイヤーを重ねる形で動作を確認したいと思います。
利用したコンテナイメージはamazonlinux:latestを使用しました。
% docker images REPOSITORY TAG IMAGE ID CREATED SIZE amazonlinux latest dc34c260f454 5 weeks ago 163MB
Diveのインストール
brew install dive
Diveの基本使用
以下のコマンドにてコンテナイメージを指定します。
% dive amazonlinux:latest
このような画面が表示されました。
画面のそれぞれを確認します。
①イメージのレイヤー一覧
コンテナイメージのレイヤー情報が出力されます。
この画面ではamazonlinuxのイメージを見ているだけなので1レイヤーのみですがDockerfileによるbuildを行うとレイヤー数が増えます。
②レイヤーダイジェスト値
コンテナのレイヤーダイジェスト値とコマンド情報が出力されます。
③イメージファイル情報
目玉の一つがこちらのイメージファイル情報です。
コンテナイメージは複数のレイヤーを重ねることによって、イメージの肥大化要因になり得るファイルが発生します。
実験的機能と明記されておりますが、余計なファイル情報の有無をスコアとサイズによって表記してくれます。
- イメージ自体のサイズ:
docker images
で確認できるイメージサイズ - 余分なスペースサイズ:余分と思われるファイルサイズ数を表示
- コンテナイメージの効率スコア:コンテナイメージがどれだけ効率的な作りとなっているかを示すスコア
④イメージ内ディレクトリ構成
2つ目の目玉がこちらです。
コンテナイメージのディレクトリ構成を確認することが出来ます。
動きを見てみる(ファイル作成編)
以下のようなDockerfileを用意してみました。
単純に/tmp
配下に1から10の連番を付与したファイルを作成します。
FROM amazonlinux:latest RUN for i in {1..10} ; do touch /tmp/testfile-${i} ; done
docker build . -t amazonlinux:test
このような結果になりました。
- 今回テストファイルを実行したコマンドがレイヤー一覧に追加
- ディレクトリ一覧の
/var
配下に連番のtestfileが緑色で表示
ファイルが追加された時は緑色でハイライトされます。
動きを見てみる(ファイル削除編)
次に作成した連番ファイルであるtestfile-6
~ testfile-10
を削除します。
FROM amazonlinux:latest RUN for i in {1..10} ; do touch /tmp/testfile-${i} ; done RUN for i in {6..10} ; do rm -f /tmp/testfile-${i} ; done
docker build . -t amazonlinux:test
このような結果になりました。
- ファイル作成編と同様に今回追加したレイヤーがレイヤー一覧に追加
- 削除された
testfile-6
~testfile-10
が赤色で表示
ファイルが削除された時は赤色でハイライトされます。
動きを見てみる(ファイル変更編)
作成済みのtestfile-1
~ testfile-5
を/
配下にmodify-testfile-1
~ modify-testfile-5
へ変更します。
FROM amazonlinux:latest RUN for i in {1..10} ; do touch /tmp/testfile-${i} ; done RUN for i in {6..10} ; do rm -f /tmp/testfile-${i} ; done RUN for i in {1..5} ; do mv /tmp/testfile-${i} modify-testfile-${i} ; done
docker build . -t amazonlinux:test
このような結果になりました。
- 元々存在していた場所からファイルが移動(削除)されたため、
testfile-1
~testfile-5
が赤色で表示 - リネームされたファイルは新規追加ファイルとして緑色で表示
動きを見てみる(ファイル容量変更)
最後にddコマンドによって、modify-testfile-1
のファイルをテストファイルに置き換えます。
FROM amazonlinux:latest RUN for i in {1..10} ; do touch /tmp/testfile-${i} ; done RUN for i in {6..10} ; do rm -f /tmp/testfile-${i} ; done RUN for i in {1..5} ; do cp /tmp/testfile-${i} testfile-${i} ; done RUN for i in {1..5} ; do mv /tmp/testfile-${i} /tmp/modify-testfile-${i} ; done RUN dd if=/dev/zero of=/tmp/modify-testfile-1 bs=10M count=1
docker build . -t amazonlinux:test
この様な結果になりました。
- ファイルサイズが変更されたため、
modify-testfile-1
が黄色で表示
便利な使い方
操作されたファイルのみ出力
Tabキーを押下することで右ペインを操作することができます。
この時に以下のキーを押下することで追加/変更/削除/未変更をフィルタリング出来ます。
キーマップ | フィルタ |
---|---|
Ctrl + A | 追加ファイル |
Ctrl + R | 削除ファイル |
Ctrl + M | 変更ファイル |
Ctrl + U | 未変更ファイル |
※Ctrl + Bはファイルパーミッション等を表示/非表示が可能です
dive build
を使ってdocker build
とdive
をシーケンシャルに起動
dive build -t <イメージ名> .
を実行することでdocker build
を実行した後にdiveを開くことが出来ます。
※.
部分はdocker build
コマンドのDockerfileパスの指定と同じなのでDockerfileが配置されているディレクトリ指定が可能です
% dive build -t amazonlinux:test . Building image... Sending build context to Docker daemon 18.19MB Step 1/8 : FROM amazonlinux:latest ---> dc34c260f454 Step 2/8 : RUN for i in {1..10} ; do touch /tmp/testfile-${i} ; done ---> Using cache ---> b6bb763d53e5 Step 3/8 : RUN for i in {6..10} ; do rm -f /tmp/testfile-${i} ; done ---> Using cache ---> 80fe5e4e730a Step 4/8 : RUN for i in {1..5} ; do cp /tmp/testfile-${i} testfile-${i} ; done ---> Using cache ---> 11339d266087 Step 5/8 : RUN for i in {1..5} ; do mv /tmp/testfile-${i} /tmp/modify-testfile-${i} ; done ---> Using cache ---> eff7d1bd1402 Step 6/8 : RUN dd if=/dev/zero of=/tmp/modify-testfile-1 bs=10M count=1 ---> Using cache ---> 38e8a0c4ce0b Step 7/8 : RUN dd if=/dev/zero of=/tmp/modify-testfile-2 bs=30M count=1 ---> Using cache ---> 31464c5894d0 Step 8/8 : RUN dd if=/dev/zero of=/tmp/modify-testfile-3 bs=40M count=1 ---> Using cache ---> 27470ae7cd0f Successfully built 27470ae7cd0f Successfully tagged amazonlinux:test Fetching image... (this can take a while with large images) Parsing image... Analyzing image... Building cache...
環境変数を指定してCI環境に対応した分析を行う
CI=true
という環境変数を渡してdiveを実行すると、予め指定された余分なファイルサイズや分析結果を評価してリターンコードをで合否を出力します。
例えばCodeBuildのbuildspecにこのリターンコードを判定する文を追加すると面白いと思います。
合格パターン
% CI=true dive amazonlinux:test ; echo $? Using default CI config Fetching image... (this can take a while with large images) Parsing image... Analyzing image... efficiency: 100.0000 % wastedBytes: 0 bytes (0 B) userWastedPercent: 0.0000 % Inefficient Files: Count Wasted Space File Path 2 0 B /tmp/testfile-5 2 0 B /tmp/testfile-4 2 0 B /tmp/testfile-3 2 0 B /tmp/testfile-2 2 0 B /tmp/testfile-1 2 0 B /tmp/testfile-9 2 0 B /tmp/testfile-8 2 0 B /tmp/testfile-7 2 0 B /tmp/testfile-6 2 0 B /tmp/testfile-10 Results: PASS: highestUserWastedPercent SKIP: highestWastedBytes: rule disabled PASS: lowestEfficiency Result:PASS [Total:3] [Passed:2] [Failed:0] [Warn:0] [Skipped:1] 0
不合格パターン
% CI=true dive amazonlinux:test ; echo $? Using default CI config Fetching image... (this can take a while with large images) Parsing image... Analyzing image... efficiency: 60.8036 % wastedBytes: 104857600 bytes (105 MB) userWastedPercent: 46.4845 % Inefficient Files: Count Wasted Space File Path 2 42 MB /tmp/modify-testfile-4 2 32 MB /tmp/modify-testfile-3 2 21 MB /tmp/modify-testfile-2 2 10 MB /tmp/modify-testfile-1 2 0 B /tmp/testfile-5 2 0 B /tmp/testfile-4 2 0 B /tmp/testfile-3 2 0 B /tmp/testfile-2 2 0 B /tmp/testfile-1 2 0 B /tmp/testfile-9 2 0 B /tmp/testfile-8 2 0 B /tmp/testfile-7 2 0 B /tmp/testfile-6 2 0 B /tmp/testfile-10 Results: FAIL: highestUserWastedPercent: too many bytes wasted, relative to the user bytes added (%-user-wasted-bytes=0.4648447895112585 > threshold=0.1) SKIP: highestWastedBytes: rule disabled FAIL: lowestEfficiency: image efficiency is too low (efficiency=0.6080361515417759 < threshold=0.9) Result:FAIL [Total:3] [Passed:0] [Failed:2] [Warn:0] [Skipped:1] 1
最後に
先日のecspressoに続きまして、今回はDiveというレイヤー分析ツールを触ってみました。
コンテナイメージの削減はコンテナ環境を運用する時に重要なポイントとなり、様々なコマンドを駆使すること形が多いと思います。
今回のツールでは手っ取り早く余分と考えられる部分を抽出出来るので使いやすいツールと思ってます。
少しでもコンテナイメージの削減を行いたい人に届くと嬉しいです。